"""
聚合各种解析方式，包括：二维码解析、文件解析、OCR解析
"""

import re
import os
import fitz
import argparse
from .qrcode_parser import get_qrcode_content
from .file_parser import FileHandle
from .ocr_parser import get_inv_data


def union_parse(path):
    """
    1. 首先使用二维码解析，如正确则返回，否则往下执行
    2. 其次使用文件解析获取信息，如正确则返回，否则继续执行
    3. 最后使用百度OCR解析，如正确则返回，否则解析错误，结束程序
    """
    if not os.path.isfile(path) or not path.endswith(('.pdf', '.PDF', '.png', '.jpg', '.jpeg', '.bmp')):
        return False, path, '无效的文件！', ''
    try:
        data = get_qrcode_content(path)
        return True, path, data, 'qrcode'
    except Exception as e:
        info = 'qrcode exception: ' + str(e)
    try:
        if path.endswith(('.pdf', '.PDF')):
            doc = fitz.Document(path)
            text = doc.load_page(0).getText()
            if text and '专用' not in text:
                handle = FileHandle(path)
                result = handle.do_parse()
                if None not in result:
                    return True, path, result, 'fitz'
                info += f'\nfitz lack: {result}'
    except Exception as e:
        info += '\nfitz exception: ' + str(e)
    try:
        result = get_inv_data(path)
        return True, path, result, 'ocr'
    except Exception as e:
        info += '\nocr exception: ' + str(e)
    return False, path, info, ''


def inv_check(inv_code, inv_num, inv_date, inv_chk, inv_money):
    """发票信息合法性检查"""
    msg = ''
    state = True
    if not re.match(r'^\d{10,12}$', inv_code):
        msg += f'发票代码不合法({inv_code})；'
        state = False
    if not re.match(r'^\d{8}$', inv_num):
        msg += f'发票号码不合法({inv_num})；'
        state = False
    if not re.match(r'^\d{8}$', inv_date):
        msg += f'开票日期不合法({inv_date})；'
        state = False
    if not re.match(r'^[a-zA-Z0-9]+$', inv_chk) and not re.match(r'^\d+\.\d+$', inv_money):
        msg += f'校验码和开具金额都不合法({inv_chk}, {inv_money})；'
        state = False
    return state, msg


def do_parse(path):
    """入口"""
    state, path, result, source = union_parse(path)
    if state:
        check_state, msg = inv_check(*result)
        return check_state, msg, path, result, source
    else:
        return state, str(result), path, result, source


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--path', type=str, required=True, help='输入文件路径')
    args = parser.parse_args()
    state, msg, path, result, source = do_parse(args.path)
    print('state:', state, '\nmessage:', msg, '\nsource:', source, '\nresult:', result)
